package com.zego.wawaji.ui.play;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.noble.library.basic.Constant;
import com.noble.library.basic.log.PLogger;
import com.noble.library.basic.sp.PSP;
import com.noble.library.observer.MsgMgr;
import com.noble.library.observer.PObserver;
import com.zego.wawaji.R;
import com.zego.wawaji.base.observer.MsgType;
import com.zego.wawaji.base.toast.PToast;
import com.zego.wawaji.base.utils.JsonUtil;
import com.zego.wawaji.message.bean.TipsMsg;
import com.zego.wawaji.third.zego.ZegoMgr;
import com.zego.wawaji.third.zego.im.callback.ZegoIMCallack;
import com.zego.wawaji.third.zego.im.callback.ZegoRoomCallback;
import com.zego.wawaji.third.zego.im.listener.ZegoListener;
import com.zego.wawaji.ui.base.BaseAppCompatActivity;
import com.zego.wawaji.ui.bean.wawa.WawaJi;
import com.zego.wawaji.ui.view.danmuku.DanMuView;
import com.zego.wawaji.ui.view.danmuku.custom.DanMuHelper;
import com.zego.wawaji.ui.view.danmuku.custom.DanmakuEntity;
import com.zego.wawaji.wawaji_client.cmd.CommandUtil;
import com.zego.wawaji.wawaji_client.play.PlayStatus;
import com.zego.zegoliveroom.ZegoLiveRoom;
import com.zego.zegoliveroom.constants.ZegoConstants;
import com.zego.zegoliveroom.entity.ZegoStreamInfo;
import com.zego.zegoliveroom.entity.ZegoUser;

import java.util.ArrayList;
import java.util.Map;

/**
 * 娃娃机游戏页
 */
public class PlayActivity extends BaseAppCompatActivity implements ZegoListener, PObserver {
    private WawaJi mRoom;
    private ZegoLiveRoom mZegoLiveRoom;

    private PlayHead head;
    private PlayHandle handle;
    private PlayFoot foot;

    private boolean isInput = false;      // 输入框是否正在展示
    private PlayInputPanel inputPanel;      // 输入框
    private LinearLayout msgContainer;

    // 引导浮层
    private RelativeLayout rlGuide;
    private ImageView ivGuide;
    private int guide;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        isCanBack(false);
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        if (intent != null) {
            mRoom = intent.getParcelableExtra("room");
        } else {
            Toast.makeText(this, "房间信息初始化错误, 请重新开始", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        if (mRoom == null) {
            PToast.showShort("房间信息获取失败, 请退出重试");
            finish();
            return;
        }

        setContentView(R.layout.activity_play);
        mZegoLiveRoom = ZegoMgr.getInstance().getZegoLiveRoom();

        initView();
        startPlay();
    }

    private void initView() {
        initGuide();
        initDanmu();

        MsgMgr.getInstance().attach(this);
        mRetryHandler = new RetryHandler(Looper.getMainLooper());

        LinearLayout headContainer = (LinearLayout) findViewById(R.id.head_container);
        LinearLayout handleContainer = (LinearLayout) findViewById(R.id.container);

        inputPanel();
        head = new PlayHead(this, mRoom, mZegoLiveRoom);
        headContainer.addView(head.getContentView());
        handle = new PlayHandle(this, mRoom, mZegoLiveRoom);
        handleContainer.addView(handle.getContentView());
        foot = new PlayFoot(this, mRoom);
        handleContainer.addView(foot.getContentView());
    }

    private void initGuide() {
        boolean firsInstall = PSP.getInstance().getBoolean(Constant.APP_FIRST_INSTALL, true);
        if (!firsInstall) {
            return;
        }
        PSP.getInstance().put(Constant.APP_FIRST_INSTALL, false);
        rlGuide = (RelativeLayout) findViewById(R.id.rl_guide);
        ivGuide = (ImageView) findViewById(R.id.iv_guide);

        rlGuide.setVisibility(View.VISIBLE);
        rlGuide.setOnClickListener(v -> {
            if (guide == 0) {
                ivGuide.setBackgroundResource(R.drawable.play_guide02);
                ++guide;
            } else if (guide == 1) {
                ivGuide.setBackgroundResource(R.drawable.play_guide03);
                ++guide;
            } else {
                rlGuide.setVisibility(View.GONE);
            }
        });
    }

    private void inputPanel() {
        msgContainer = (LinearLayout) findViewById(R.id.play_msg_container);
        inputPanel = new PlayInputPanel(this);
        msgContainer.addView(inputPanel.getContentView());

        findViewById(R.id.play_mask).setOnTouchListener((v, event) -> {
            if (isInput) {
                msgContainer.setVisibility(View.INVISIBLE);
                inputPanel.refresh(View.GONE);
                isInput = false;
            }
            return false;
        });

        inputPanel.setInputPanelListener(v -> {
            if (isInput) {
                msgContainer.setVisibility(View.INVISIBLE);
                inputPanel.refresh(View.GONE);
                isInput = false;
            }
        });
    }

    public void showInputPanel() {
        if (!isInput) {
            msgContainer.setVisibility(View.VISIBLE);
            inputPanel.refresh(View.VISIBLE);
            isInput = true;
        }
    }

    private void startPlay() {
        if (loginRoom()) { // 登录房间成功
            setupCallbacks();  // 登录房间成功后设置回调
            head.netStatus();
            head.setupCallbacks(this);
        }
    }

    private Handler mRetryHandler;
    private ZegoStreamInfo streamInfo;
    private int audienceNum;            // 观众人数

    /**
     * 登录房间操作： 不成功重试登录
     */
    private boolean loginRoom() {
        return mZegoLiveRoom.loginRoom(mRoom.getRoomId(), ZegoConstants.RoomRole.Audience, (errCode, zegoStreamInfos) -> {
            if (errCode == 0) {
                mRetryHandler.removeMessages(RetryHandler.MSG_RELOGIN_ROOM);
                for (ZegoStreamInfo stream : zegoStreamInfos) {
                    // {"player":{"id":"","name":""},"queue_number":0,"total":1}
                    PLogger.d("kjksdjkfak---------1111::" + stream.extraInfo);
                    if (!TextUtils.isEmpty(stream.extraInfo)) {
                        streamInfo = stream;

                        Map<String, Object> map = JsonUtil.getMapFromJson(stream.extraInfo);
                        if (map != null) {
                            int count = ((Double) map.get("queue_number")).intValue();
                            handle.refreshQueueNum(count);
                            handle.parseQueueNum((ArrayList) map.get("queue"));

                            audienceNum = ((Double) map.get("total")).intValue();
                            head.refreshUserCount(audienceNum);

                            if (imCallack != null) {
                                imCallack.setAudienceNum(audienceNum);
                            }
                        }
                    }
                }
                setAnchor();
            } else {    // 失败后重新登录
                PLogger.d("kjksdjkfak---------2222");
                mRetryHandler.sendEmptyMessageDelayed(RetryHandler.MSG_RELOGIN_ROOM, 100);
            }
        });
    }

    private void setAnchor() {
        ZegoUser zegoUser = new ZegoUser();

        // 180106113506597, WWJS_rk7130s_180106113506597
        if (streamInfo == null) {
            zegoUser.userID = "";
            zegoUser.userName = "";
        } else {
            zegoUser.userID = TextUtils.isEmpty(streamInfo.userID) ? "" : streamInfo.userID;
            zegoUser.userName = TextUtils.isEmpty(streamInfo.userName) ? "" : streamInfo.userName;
        }
        CommandUtil.getInstance().setAnchor(zegoUser);
        MsgMgr.getInstance().sendMsg(MsgType.MT_Init_Suc, true);
    }

    @Override
    public void onMessage(String key, Object value) {
        switch (key) {
            case MsgType.MT_App_Notification:
                addRichDanmu((String) value);
                break;

            case MsgType.MT_User_JoinIn:
                addSystemDanmu((String) value);
                break;
        }
    }

    /**
     * 登录房间失败或推流失败后，重新登录
     */
    private class RetryHandler extends Handler {
        static final int MSG_RELOGIN_ROOM = 1;

        public RetryHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_RELOGIN_ROOM:
                    loginRoom();
                    break;

                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    }

    /**
     * 处理来自服务器的消息.
     */
    private void handleRecvCustomCMD(String msg) {
        Map<String, Object> map = JsonUtil.getMapFromJson(msg);
        if (map == null) return;

        int cmd = ((Double) map.get("cmd")).intValue();
        int rspSeq = ((Double) map.get("seq")).intValue();
        PlayHelper.rspSeq = rspSeq;
        Map<String, Object> data = (Map<String, Object>) map.get("data");

        if (data != null) {
            // 解析预约队列用户列表
            handle.parseQueueNum((ArrayList) data.get("queue"));
        }
        switch (cmd) {
            case CommandUtil.CMD_APPLY_RESULT:    // 预约结果
                handle.handleApplyResult(data);
                break;
            case CommandUtil.CMD_CANCEL_APPOINTMENT_REPLY: // 取消预约
                break;
            case CommandUtil.CMD_GAME_READY:
                PlayHelper.handleGameReady(this, rspSeq, data);
                break;
            case CommandUtil.CMD_CONFIRM_BOARD_REPLY:
                handle.handleConfirmBoardReply(data);
                break;
            case CommandUtil.CMD_GAME_RESULT:
                handle.stopWaitGameResultTimer();
                PlayHelper.handleGameResult(rspSeq, data);
                break;
            case CommandUtil.CMD_USER_UPDATE:
                break;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (head != null)
                head.logout();
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (head != null && head.isPlaying) {
            PlayHelper.playSound();
        }
        handle.refreshCoin();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (head != null && head.isPlaying) {
            PlayHelper.stopPlay();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    public void finish() {
        super.finish();
        doLogout();
        MsgMgr.getInstance().detach(this);
    }

    private void doLogout() {
        try {
            PlayHelper.reset();
            CommandUtil.getInstance().reset();
            PlayStatus.resetStatus();
            mRetryHandler.removeCallbacksAndMessages(null);
            MsgMgr.getInstance().sendMsg(MsgType.MT_Update_MyInfo, null);
            if (head != null)
                head.doLogout();
            if (handle != null)
                handle.doLogout();
            foot.doLogout();
            mZegoLiveRoom.logoutRoom();
            if (imCallack != null) {
                imCallack.release();
                imCallack = null;
            }
        } catch (Exception e) {
        }
    }

    // =======================================  接口回调 ====================================
    private ZegoIMCallack imCallack = new ZegoIMCallack(this);

    /**
     * 设置各种回调监听
     */
    private void setupCallbacks() {
        mZegoLiveRoom.setZegoIMCallback(imCallack);
        mZegoLiveRoom.setZegoRoomCallback(new ZegoRoomCallback(this));
    }

    @Override
    public void roomTotalNum(int num) {
        head.refreshUserCount(num);
    }

    @Override
    public void onRecvCustomCommand(String fromUserId, String fromUserName, String content, String roomId) {
        // 只接收当前房间，当前主播发来的消息
        if (CommandUtil.getInstance().isCommandFromAnchor(fromUserId) && mRoom.getRoomId().equals(roomId)) {
            if (!TextUtils.isEmpty(content)) {
                handleRecvCustomCMD(content);
            }
        }
    }

    @Override
    public void onPlayStateUpdate(int errCode, String streamID) {
        head.refreshPlayStateUpdate(errCode, streamID);
    }

    @Override
    public void onVideoSizeChangedTo(String streamID, int i, int i1) {
        head.refreshVideoSizeChangedTo(streamID, i, i1);
    }

    // ===================================== Danmu消息 ==============================
    private DanMuHelper mDanMuHelper;
    private DanMuView mDanMuContainerBroadcast;
    private TipsMsg tipsMsg;

    private void initDanmu() {
        mDanMuContainerBroadcast = (DanMuView) findViewById(R.id.danmaku_container_room);
        mDanMuContainerBroadcast.prepare();

        mDanMuHelper = new DanMuHelper(this);
        mDanMuHelper.add(mDanMuContainerBroadcast);
    }

    private void addRichDanmu(String content) {
        tipsMsg = new TipsMsg();
        tipsMsg.parseJson(content);

        DanmakuEntity danmakuEntity = new DanmakuEntity();
        danmakuEntity.setType(DanmakuEntity.DANMAKU_TYPE_USERCHAT);
        danmakuEntity.setName(tipsMsg.getNickName());
        danmakuEntity.setAvatar(tipsMsg.getAvatar());
        danmakuEntity.setText(tipsMsg.getContent());
        addRoomDanmaku(danmakuEntity);
    }

    private void addSystemDanmu(String content) {
        DanmakuEntity danmakuEntity = new DanmakuEntity();
        danmakuEntity.setType(DanmakuEntity.DANMAKU_TYPE_SYSTEM);
        danmakuEntity.setText(content);
        addRoomDanmaku(danmakuEntity);
    }

    /**
     * 发送一条房间内的弹幕
     */
    private void addRoomDanmaku(DanmakuEntity danmakuEntity) {
        if (mDanMuHelper != null) {
            mDanMuHelper.addDanMu(danmakuEntity, true);
        }
    }

    @Override
    protected void onDestroy() {
        if (mDanMuHelper != null) {
            mDanMuHelper.release();
            mDanMuHelper = null;
        }
        super.onDestroy();
    }
}
